// f[i][j][0] := 以i为节点的子树上（包括i）有 j 个点不用作原树边的匹配，且 i
// 没有用作原树边匹配的最大权匹配
//
// f[i][j][1] := 以i为节点的子树上（包括i）有 j
// 个点不用作原树边的匹配，且 i 用作原树边匹配的最大权匹配
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5 + 10;
const ll M = 210;  // 要开边数的两倍
const ll inf = 0x3f3f3f3f3f3f3f3f;

struct node {
  ll to;
  ll len;
};

vector<node> g[N];
ll n, k;
ll p;
ll f[N][M][2], tmp[M][2];
ll sz[N];

void dfs(ll x, ll p) {
  sz[x] = 1;
  f[x][0][0] = 0;
  f[x][1][1] = 0;

  for (auto uu : g[x]) {
    ll to = uu.to;
    ll len = uu.len;
    if (to == p) continue;

    dfs(to, x);

    for (ll i = 0; i <= k * 2; ++i) {
      tmp[i][0] = f[x][i][0];
      tmp[i][1] = f[x][i][1];
    }
    for (ll i = 0; i <= min(sz[x], k * 2); ++i) {
      for (ll j = 0; j <= min(sz[to], k * 2); ++j) {
        if (i + j > 2ll * k) continue;
        tmp[i + j][0] =
            max(tmp[i + j][0], f[x][i][0] + max(f[to][j][0], f[to][j][1]));
        tmp[i + j][1] =
            max(tmp[i + j][1], f[x][i][1] + max(f[to][j][0], f[to][j][1]));
        tmp[i + j][1] = max(tmp[i + j][1], f[x][i][0] + f[to][j][0] + len);
      }
    }
    for (ll i = 0; i <= min(sz[x], k * 2); ++i) {
      for (ll j = 0; j <= min(sz[to], k * 2); ++j) {
        f[x][i + j][0] = tmp[i + j][0];
        f[x][i + j][1] = tmp[i + j][1];
      }
    }
    sz[x] += sz[to];
  }
}

signed main() {
  scanf("%lld%lld%lld", &n, &k, &p);

  ll len;
  for (ll i = 0, u, v; i < n - 1; ++i) {
    scanf("%lld%lld%lld", &u, &v, &len);
    g[u].push_back({v, len});
    g[v].push_back({u, len});
  }
  ll mn = min(n, k * 2);

  for (int i = 0; i <= n; ++i) {
    for (int j = 0; j <= mn; ++j) {
      f[i][j][0] = -inf;
      f[i][j][1] = -inf;
    }
  }

  dfs(1, -1);

  ll ans = 0;

  for (ll i = 0; i <= mn; ++i) {
    ans = max(ans, max(f[1][i][0], f[1][i][1]) + (ll)i / 2 * p);
  }

  printf("%lld", ans);

  return 0;
}
